package config

import (
	types "com.yy.api/my_gateway/internal/providers"
	"github.com/spf13/viper"
)

type Config struct {
	Port     int `mapstructure:"port"`
	Services struct {
		LLM struct {
			APIKeys []string `mapstructure:"api_keys"`
		} `mapstructure:"llm"`
	} `mapstructure:"services"`

	Cache struct {
		RateLimit struct {
			LimitPerMinute int    `mapstructure:"limit_per_minute"`
			RedisAddr      string `mapstructure:"redis_addr"`
		} `mapstructure:"rate_limit"`
	} `mapstructure:"cache"`
	Providers map[string]*types.Provider
	Models    map[string]*types.Model
}

func LoadFullConfig(configPath, providersPath, modelsPath string) (*Config, error) {
	var cfg Config
	viper.SetConfigFile(configPath)
	if err := viper.ReadInConfig(); err != nil {
		return nil, err
	}
	if err := viper.Unmarshal(&cfg); err != nil {
		return nil, err
	}
	providersMap, err := reloadConfig[*types.Provider](providersPath)
	if err != nil {
		return nil, err
	}
	cfg.Providers = providersMap
	modelsMap, err := reloadConfig[*types.Model](modelsPath)
	if err != nil {
		return nil, err
	}
	cfg.Models = modelsMap
	return &cfg, nil
}

func reloadConfig[T types.Identifiable](path string) (map[string]T, error) {
	viper.Reset()
	viper.SetConfigFile(path)
	if err := viper.ReadInConfig(); err != nil {
		return nil, err
	}
	var response struct {
		Data []T `json:"data" mapstructure:"data"`
	}
	if err := viper.Unmarshal(&response); err != nil {
		return nil, err
	}
	result := make(map[string]T)
	for _, item := range response.Data {
		result[item.GetID()] = item
	}
	return result, nil
}
